#include "../../includes/common/common.h"
#include "../../includes/QsLog/QsLog.h"
#include "../../includes/breakpad/exception_handler.h"

#include <QDir>

using namespace QsLogging;

bool dump_callback(const wchar_t *dump_path, const wchar_t *id, void *content, EXCEPTION_POINTERS *exinfo, MDRawAssertionInfo *assertion, bool succeeded)
{
    if(succeeded)
    {
        QLOG_ERROR()<<"系统已经崩溃,dmp已经生成成功,请联系开发人员!";
    }
    else
    {
        QLOG_ERROR()<<"系统已经崩溃,dmp生成失败,请联系开发人员!";
    }

    return succeeded;
}

/**
 * @brief init_lib_resources 加载本静态库的资源
 */
void init_lib_resources(void)
{
    Q_INIT_RESOURCE(libqtcore);
}

/**
 * @brief clean_lib_resources 卸载本静态库的资源
 */
void cleanup_lib_resources(void)
{
    Q_CLEANUP_RESOURCE(libqtcore);
}

/**
 * @brief init_log_file 生成日志文件
 * @param filepath 要生成的日志文件路径
 */
void init_log_file(QString filepath)
{
    if(filepath.isEmpty())
        return;

    // 初始化日志机制
    Logger& logger = Logger::instance();
    logger.setLoggingLevel(QsLogging::TraceLevel);

    // 添加文件为目的地
    const QString sLogPath(QDir(QApplication::applicationDirPath()).filePath(filepath));
    DestinationPtr fileDestination(DestinationFactory::MakeFileDestination(
      sLogPath, EnableLogRotation, MaxSizeBytes(512*1024), MaxOldLogCount(5)));
    logger.addDestination(fileDestination);

    QLOG_INFO()<<"log system init success.";
}

/**
 * @brief sava_file 保存源文件到目标文件(主要网络传输中使用)
 * @param srcfile 要保存的源文件的路径(相对路径)
 * @param decfile 目标文件路径(绝对路径)
 *
 * @return 如果文件保存成功返回真，否则返回假
 */
bool sava_file(QString srcfile,QString decfile)
{
    bool preturnState = true;

    QString appfiledir = decfile;
    QString tmpFileDirPath = appfiledir.mid(0,appfiledir.lastIndexOf("/"));

    QDir dir(tmpFileDirPath);
    if(!dir.exists())
    {
        if(!dir.mkpath(tmpFileDirPath))
        {
            QLOG_ERROR()<<"sava_file:"<<tmpFileDirPath<<" create fail.";
            preturnState=false;
        }
    }

    QFileInfo pFileInfo(appfiledir);
    if(pFileInfo.exists())
    {
        if(!QFile::remove(appfiledir))
        {
            QLOG_ERROR()<<"sava_file:"<<appfiledir<<" remove fail.";
            preturnState=false;
        }
    }

    if(!QFile::copy(srcfile,appfiledir))
    {
       QLOG_ERROR()<<"sava_file:"<<appfiledir<<" copy fail.";
       preturnState=false;
    }

    return preturnState;
}

/**
 * @brief init_dump_system 初始化崩溃系统
 */
void init_dump_system(void)
{
    google_breakpad::ExceptionHandler eh(
        L".", NULL, dump_callback, NULL, google_breakpad::ExceptionHandler::HANDLER_ALL);
}

//拷贝文件：
bool copyFileToPath(QString sourceDir ,QString toDir, bool coverFileIfExist)
{
	toDir.replace("\\","/");
	if (sourceDir == toDir){
		return true;
	}
	if (!QFile::exists(sourceDir)){
		return false;
	}
	QDir *createfile     = new QDir;
	bool exist = createfile->exists(toDir);
	if (exist){
		if(coverFileIfExist){
			createfile->remove(toDir);
		}
	}//end if
 
	if(!QFile::copy(sourceDir, toDir))
	{
		return false;
	}
	return true;
}
 
//拷贝文件夹：
bool copyDirectoryFiles(const QString &fromDir, const QString &toDir, bool coverFileIfExist)
{
	QDir sourceDir(fromDir);
	QDir targetDir(toDir);
	if(!targetDir.exists()){    /**< 如果目标目录不存在，则进行创建 */
		if(!targetDir.mkdir(targetDir.absolutePath()))
			return false;
	}
 
	QFileInfoList fileInfoList = sourceDir.entryInfoList();
	foreach(QFileInfo fileInfo, fileInfoList){
		if(fileInfo.fileName() == "." || fileInfo.fileName() == "..")
			continue;
 
		if(fileInfo.isDir()){    /**< 当为目录时，递归的进行copy */
			if(!copyDirectoryFiles(fileInfo.filePath(), 
				targetDir.filePath(fileInfo.fileName()),
				coverFileIfExist))
				return false;
		}
		else{            /**< 当允许覆盖操作时，将旧文件进行删除操作 */
			if(coverFileIfExist && targetDir.exists(fileInfo.fileName())){
				targetDir.remove(fileInfo.fileName()); 
			}
 
			/// 进行文件copy
			if(!QFile::copy(fileInfo.filePath(), 
				targetDir.filePath(fileInfo.fileName()))){
					return false;
			}
		}
	}
	return true;
}

/**
 * 得到指定目录下所有的文件
 *
 * @param _filePath 要得到文件的目录
 * @param filelist 用于存放读取到的文件
 * @return 如果文件读取成功返回0，否则返回-1
 */
int FindFile(const QString& _filePath,QVector<QString> &filelist)
{
    QDir dir(_filePath);

    if (!dir.exists()) {
        return -1;
    }

    //取到所有的文件和文件名，但是去掉.和..的文件夹（这是QT默认有的）
    dir.setFilter(QDir::Dirs|QDir::Files|QDir::NoDotAndDotDot);

    //文件夹优先
    dir.setSorting(QDir::DirsFirst);

    //转化成一个list
    QFileInfoList list = dir.entryInfoList();
    //QStringList infolist = dir.entryList(QDir::Files | QDir::NoDotAndDotDot);
    if(list.size()< 1 ) {
        return -1;
    }
    int i=0;

    //递归算法的核心部分
    do{
        QFileInfo fileInfo = list.at(i);
        //如果是文件夹，递归
        bool bisDir = fileInfo.isDir();
        if(bisDir) {
            FindFile(fileInfo.filePath(),filelist);
        }
        else{
            filelist.push_back(list[i].absoluteFilePath());
        }//end else
        i++;
    } while(i < list.size());

    return 0;
}

/**
 * @brief JsonToString QJsonObject转QString
 * @param json 要转换的QJsonObject
 * @return 返回转换后的字符串
 */
QString JsonToString(const QJsonObject& json)
{
    return QString(QJsonDocument(json).toJson(QJsonDocument::Compact));
}

/**
 * @brief StringToJson QString转QJsonObject
 * @param str 要转换的字符串
 * @return 返回转换后的QJsonObject
 */
QJsonObject StringToJson(const QString& str)
{
    QJsonObject l_ret;

    QJsonParseError l_err;
    QJsonDocument l_doc = QJsonDocument::fromJson(str.toUtf8(), &l_err);
    if (l_err.error == QJsonParseError::NoError)
    {
        if (l_doc.isObject())
        {
            l_ret = l_doc.object();
        }
    }
    return l_ret;
}

/// 删除目录下所有文件和文件夹
bool removeFolderContent(const QString &folderDir)
{
    QDir dir(folderDir);
    QFileInfoList fileList;
    QFileInfo curFile;
    if(!dir.exists())  {return false;}//文件不存，则返回false
    fileList=dir.entryInfoList(QDir::Dirs|QDir::Files
                               |QDir::Readable|QDir::Writable
                               |QDir::Hidden|QDir::NoDotAndDotDot
                               ,QDir::Name);
    while(fileList.size()>0)
    {
        int infoNum=fileList.size();
        for(int i=infoNum-1;i>=0;i--)
        {
            curFile=fileList[i];
            if(curFile.isFile())//如果是文件，删除文件
            {
                QFile fileTemp(curFile.filePath());
                fileTemp.remove();
                fileList.removeAt(i);
            }
            if(curFile.isDir())//如果是文件夹
            {
                QDir dirTemp(curFile.filePath());
                QFileInfoList fileList1=dirTemp.entryInfoList(QDir::Dirs|QDir::Files
                                                              |QDir::Readable|QDir::Writable
                                                              |QDir::Hidden|QDir::NoDotAndDotDot
                                                              ,QDir::Name);
                if(fileList1.size()==0)//下层没有文件或文件夹
                {
                    dirTemp.rmdir(".");
                    fileList.removeAt(i);
                }
                else//下层有文件夹或文件
                {
                    for(int j=0;j<fileList1.size();j++)
                    {
                        if(!(fileList.contains(fileList1[j])))
                            fileList.append(fileList1[j]);
                    }
                }
            }
        }
    }

    dir.removeRecursively();

    return true;
}
